/*     */ package com.zimbra.cs.index;
/*     */ 
/*     */ import com.google.common.collect.Sets;
/*     */ import com.google.common.io.Closeables;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import java.io.Closeable;
/*     */ import java.io.IOException;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class IntersectionQueryOperation
/*     */   extends CombiningQueryOperation
/*     */ {
/*     */   private boolean noHits;
/*     */   private List<ZimbraHit> bufferedNext;
/*     */   private HitGrouper[] messageGrouper;
/*     */   
/*     */   public IntersectionQueryOperation()
/*     */   {
/*  36 */     this.noHits = false;
/*  37 */     this.bufferedNext = new ArrayList(1);
/*  38 */     this.messageGrouper = null;
/*     */   }
/*     */   
/*     */   public long getCursorOffset() {
/*  42 */     return -1L;
/*     */   }
/*     */   
/*     */   public void resetIterator() throws ServiceException
/*     */   {
/*  47 */     this.bufferedNext.clear();
/*  48 */     for (int i = 0; i < this.messageGrouper.length; i++) {
/*  49 */       this.messageGrouper[i].resetIterator();
/*     */     }
/*     */   }
/*     */   
/*     */   public ZimbraHit getNext() throws ServiceException
/*     */   {
/*  55 */     if ((this.noHits) || (!hasNext())) {
/*  56 */       return null;
/*     */     }
/*  58 */     return (ZimbraHit)this.bufferedNext.remove(0);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   void bufferNextHits()
/*     */     throws ServiceException
/*     */   {
/*  68 */     if (this.bufferedNext.size() > 0) {
/*     */       return;
/*     */     }
/*     */     for (;;) {
/*  72 */       if (!this.messageGrouper[0].bufferNextHits()) {
/*  73 */         return;
/*     */       }
/*  75 */       ZimbraLog.search.debug("MsgGrp0: %s", new Object[] { this.messageGrouper[0] });
/*  76 */       ZimbraHit curHit = this.messageGrouper[0].getGroupHit();
/*  77 */       int msgId = this.messageGrouper[0].getCurMsgId();
/*     */       
/*     */ 
/*     */ 
/*  81 */       for (int i = 1;; i++) { if (i >= this.messageGrouper.length)
/*     */           break label128;
/*  83 */         if (!this.messageGrouper[i].bufferNextHits(curHit)) {
/*     */           break;
/*     */         }
/*     */         
/*  87 */         ZimbraLog.search.debug("MsgGrp[%d]: %s", new Object[] { Integer.valueOf(i), this.messageGrouper[i] });
/*     */       }
/*     */       label128:
/*  90 */       List<Integer> seenMsgs = new ArrayList();
/*     */       do
/*     */       {
/*  93 */         if ((curHit != null) && (msgId > 0))
/*     */         {
/*     */ 
/*  96 */           for (int i = 0; i < this.messageGrouper.length; i++) {
/*  97 */             this.messageGrouper[i].setMsgId(msgId);
/*  98 */             ZimbraHit hit = this.messageGrouper[i].getNextHit();
/*  99 */             while (hit != null) {
/* 100 */               if (!this.bufferedNext.contains(hit)) {
/* 101 */                 boolean ok = true;
/* 102 */                 for (int j = 0; (ok) && (j < this.messageGrouper.length); j++) {
/* 103 */                   if (j != i) {
/* 104 */                     if ((hit instanceof MessageHit)) {
/* 105 */                       if (!this.messageGrouper[j].intersectWithBuffer((MessageHit)hit)) {
/* 106 */                         ok = false;
/*     */                       }
/* 108 */                     } else if (((hit instanceof MessagePartHit)) && 
/* 109 */                       (!this.messageGrouper[j].intersectWithBuffer((MessagePartHit)hit))) {
/* 110 */                       ok = false;
/*     */                     }
/*     */                   }
/*     */                 }
/*     */                 
/* 115 */                 if (ok) {
/* 116 */                   this.bufferedNext.add(hit);
/*     */                 }
/*     */               }
/* 119 */               hit = this.messageGrouper[i].getNextHit();
/*     */             }
/*     */           }
/*     */         }
/*     */         
/* 124 */         seenMsgs.add(Integer.valueOf(msgId));
/* 125 */         msgId = this.messageGrouper[0].getNextMessageId(seenMsgs);
/* 126 */       } while (msgId > 0);
/*     */       
/* 128 */       if (this.bufferedNext.size() > 0) {
/*     */         break;
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */ 
/* 135 */     for (int i = 0; i < this.bufferedNext.size(); i++) {
/* 136 */       ZimbraHit hit = (ZimbraHit)this.bufferedNext.get(i);
/* 137 */       ZimbraLog.search.debug("BUFFERED: %s", new Object[] { hit });
/*     */     }
/*     */   }
/*     */   
/*     */   public ZimbraHit peekNext() throws ServiceException
/*     */   {
/* 143 */     if (this.noHits) {
/* 144 */       return null;
/*     */     }
/* 146 */     bufferNextHits();
/* 147 */     if (this.bufferedNext.size() > 0) {
/* 148 */       return (ZimbraHit)this.bufferedNext.get(0);
/*     */     }
/* 150 */     return null;
/*     */   }
/*     */   
/*     */ 
/*     */   public void close()
/*     */     throws IOException
/*     */   {
/* 157 */     for (QueryOperation op : this.operations) {
/* 158 */       op.close();
/*     */     }
/*     */   }
/*     */   
/*     */   public ZimbraHit skipToHit(int hitNo) throws ServiceException
/*     */   {
/* 164 */     if (this.noHits) {
/* 165 */       return null;
/*     */     }
/* 167 */     return super.skipToHit(hitNo);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static final class HitGrouper
/*     */   {
/*     */     private final QueryOperation subOp;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     private final SortBy sortOrder;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 192 */     private final List<ZimbraHit> bufferedHit = new ArrayList();
/* 193 */     private int curMsgId = -1;
/* 194 */     private ZimbraHit groupHit = null;
/* 195 */     private int curBufPos = 0;
/*     */     
/*     */     public String toString()
/*     */     {
/* 199 */       StringBuffer toRet = new StringBuffer(this.subOp.toString()).append("\n\t");
/* 200 */       for (int i = 0; i < this.bufferedHit.size(); i++) {
/* 201 */         ZimbraHit hit = (ZimbraHit)this.bufferedHit.get(i);
/* 202 */         toRet.append(hit.toString()).append("\n\t");
/*     */       }
/* 204 */       return toRet.toString();
/*     */     }
/*     */     
/*     */     HitGrouper(QueryOperation subOperation, SortBy sort) {
/* 208 */       this.subOp = subOperation;
/* 209 */       this.sortOrder = sort;
/*     */     }
/*     */     
/*     */     void resetIterator() throws ServiceException {
/* 213 */       this.bufferedHit.clear();
/* 214 */       this.subOp.resetIterator();
/* 215 */       this.curMsgId = -1;
/* 216 */       this.groupHit = null;
/* 217 */       this.curBufPos = 0;
/*     */     }
/*     */     
/*     */     int getNextMessageId(List<Integer> seenMsgs) throws ServiceException
/*     */     {
/* 222 */       for (int i = 1; i < this.bufferedHit.size(); i++) {
/* 223 */         Integer checkId = Integer.valueOf(((ZimbraHit)this.bufferedHit.get(i)).getItemId());
/* 224 */         if (!seenMsgs.contains(checkId)) {
/* 225 */           return checkId.intValue();
/*     */         }
/*     */       }
/* 228 */       return -1;
/*     */     }
/*     */     
/*     */ 
/*     */     boolean bufferNextHits()
/*     */       throws ServiceException
/*     */     {
/* 235 */       this.bufferedHit.clear();
/*     */       
/*     */ 
/* 238 */       if (!this.subOp.hasNext()) {
/* 239 */         return false;
/*     */       }
/* 241 */       this.groupHit = this.subOp.getNext();
/* 242 */       setMsgId(this.groupHit.getItemId());
/* 243 */       this.bufferedHit.add(this.groupHit);
/*     */       
/*     */ 
/* 246 */       while (this.subOp.hasNext()) {
/* 247 */         ZimbraHit hit = this.subOp.peekNext();
/*     */         
/* 249 */         if (hit.compareTo(this.sortOrder, this.groupHit) == 0) {
/* 250 */           this.bufferedHit.add(hit);
/*     */           
/* 252 */           ZimbraHit check = this.subOp.getNext();
/* 253 */           assert (check == hit);
/*     */         } else {
/* 255 */           return !this.bufferedHit.isEmpty();
/*     */         }
/*     */       }
/* 258 */       return !this.bufferedHit.isEmpty();
/*     */     }
/*     */     
/*     */     int getCurMsgId() {
/* 262 */       return this.curMsgId;
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     ZimbraHit getGroupHit()
/*     */     {
/* 274 */       return this.groupHit;
/*     */     }
/*     */     
/*     */     void setMsgId(int msgId) {
/* 278 */       this.curMsgId = msgId;
/* 279 */       this.curBufPos = 0;
/*     */     }
/*     */     
/*     */     ZimbraHit getNextHit() throws ServiceException {
/* 283 */       while (this.curBufPos < this.bufferedHit.size()) {
/* 284 */         if (((ZimbraHit)this.bufferedHit.get(this.curBufPos)).getItemId() == this.curMsgId) {
/* 285 */           this.curBufPos += 1;
/* 286 */           return (ZimbraHit)this.bufferedHit.get(this.curBufPos - 1);
/*     */         }
/* 288 */         this.curBufPos += 1;
/*     */       }
/* 290 */       return null;
/*     */     }
/*     */     
/*     */     boolean intersectWithBuffer(MessageHit hit) throws ServiceException {
/* 294 */       int hitMsgId = hit.getItemId();
/* 295 */       for (int i = 0; i < this.bufferedHit.size(); i++) {
/* 296 */         if (((ZimbraHit)this.bufferedHit.get(i)).getItemId() == hitMsgId) {
/* 297 */           return true;
/*     */         }
/*     */       }
/* 300 */       return false;
/*     */     }
/*     */     
/*     */ 
/*     */     boolean intersectWithBuffer(MessagePartHit hit)
/*     */       throws ServiceException
/*     */     {
/* 307 */       int hitMsgId = hit.getItemId();
/* 308 */       for (int i = 0; i < this.bufferedHit.size(); i++) {
/* 309 */         ZimbraHit bufHit = (ZimbraHit)this.bufferedHit.get(i);
/* 310 */         if (bufHit.getItemId() == hitMsgId) {
/* 311 */           if ((bufHit instanceof MessagePartHit)) {
/* 312 */             MessagePartHit mph = (MessagePartHit)bufHit;
/* 313 */             if (mph == hit) {
/* 314 */               return true;
/*     */             }
/*     */           }
/*     */           else {
/* 318 */             return true;
/*     */           }
/*     */         }
/*     */       }
/* 322 */       return false;
/*     */     }
/*     */     
/*     */ 
/*     */     boolean bufferNextHits(ZimbraHit curHit)
/*     */       throws ServiceException
/*     */     {
/* 329 */       this.groupHit = curHit;
/* 330 */       this.bufferedHit.clear();
/*     */       
/* 332 */       if (!this.subOp.hasNext()) {
/* 333 */         return false;
/*     */       }
/*     */       
/* 336 */       ZimbraHit newStamp = null;
/* 337 */       while ((newStamp = this.subOp.peekNext()) != null) {
/* 338 */         int result = newStamp.compareTo(this.sortOrder, this.groupHit);
/* 339 */         if (result == 0) {
/* 340 */           this.bufferedHit.add(newStamp);
/*     */           
/* 342 */           ZimbraHit check = this.subOp.getNext();
/* 343 */           assert (check == newStamp);
/* 344 */         } else if (result < 0)
/*     */         {
/*     */ 
/* 347 */           this.subOp.getNext();
/*     */ 
/*     */         }
/*     */         else
/*     */         {
/*     */ 
/* 353 */           return this.bufferedHit.size() > 0;
/*     */         }
/*     */       }
/* 356 */       return this.bufferedHit.size() > 0;
/*     */     }
/*     */   }
/*     */   
/*     */   boolean hasSpamTrashSetting()
/*     */   {
/* 362 */     for (QueryOperation op : this.operations) {
/* 363 */       if (op.hasSpamTrashSetting()) {
/* 364 */         return true;
/*     */       }
/*     */     }
/* 367 */     return false;
/*     */   }
/*     */   
/*     */   void forceHasSpamTrashSetting()
/*     */   {
/* 372 */     if (!$assertionsDisabled) throw new AssertionError();
/* 373 */     for (QueryOperation op : this.operations) {
/* 374 */       op.forceHasSpamTrashSetting();
/*     */     }
/*     */   }
/*     */   
/*     */   Set<QueryTarget> getQueryTargets()
/*     */   {
/* 380 */     Set<QueryTarget> result = Sets.newHashSet();
/*     */     
/* 382 */     Iterator<QueryOperation> itr = this.operations.iterator();
/* 383 */     if (itr.hasNext()) {
/* 384 */       result.addAll(((QueryOperation)itr.next()).getQueryTargets());
/*     */       
/*     */ 
/* 387 */       while (itr.hasNext()) {
/* 388 */         Set<QueryTarget> set = ((QueryOperation)itr.next()).getQueryTargets();
/*     */         
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 396 */         if (result.contains(QueryTarget.UNSPECIFIED)) {
/* 397 */           if (set.contains(QueryTarget.UNSPECIFIED)) {
/* 398 */             result.addAll(set);
/*     */           } else {
/* 400 */             result.clear();
/* 401 */             result.addAll(set);
/*     */           }
/* 403 */         } else if (!set.contains(QueryTarget.UNSPECIFIED)) {
/* 404 */           result.retainAll(set);
/*     */         }
/*     */       }
/*     */     }
/* 408 */     return result;
/*     */   }
/*     */   
/*     */   boolean hasNoResults()
/*     */   {
/* 413 */     return false;
/*     */   }
/*     */   
/*     */   boolean hasAllResults()
/*     */   {
/* 418 */     return false;
/*     */   }
/*     */   
/*     */   QueryOperation expandLocalRemotePart(Mailbox mbox) throws ServiceException
/*     */   {
/* 423 */     List<QueryOperation> newList = new ArrayList();
/* 424 */     for (QueryOperation op : this.operations) {
/* 425 */       newList.add(op.expandLocalRemotePart(mbox));
/*     */     }
/* 427 */     this.operations = newList;
/* 428 */     return this;
/*     */   }
/*     */   
/*     */   QueryOperation ensureSpamTrashSetting(Mailbox mbox, boolean includeTrash, boolean includeSpam)
/*     */     throws ServiceException
/*     */   {
/* 434 */     if (!hasSpamTrashSetting())
/*     */     {
/*     */ 
/* 437 */       List<QueryOperation> newList = new ArrayList();
/* 438 */       for (QueryOperation op : this.operations) {
/* 439 */         newList.add(op.ensureSpamTrashSetting(mbox, includeTrash, includeSpam));
/*     */       }
/* 441 */       this.operations = newList;
/*     */     }
/* 443 */     return this;
/*     */   }
/*     */   
/*     */   public void addQueryOp(QueryOperation op) {
/* 447 */     assert (op != null);
/* 448 */     this.operations.add(op);
/*     */   }
/*     */   
/*     */   private void addQueryOps(List<QueryOperation> ops) {
/* 452 */     this.operations.addAll(ops);
/*     */   }
/*     */   
/*     */   void pruneIncompatibleTargets(Set<QueryTarget> targets) {
/* 456 */     for (QueryOperation op : this.operations) {
/* 457 */       if ((op instanceof UnionQueryOperation)) {
/* 458 */         ((UnionQueryOperation)op).pruneIncompatibleTargets(targets);
/* 459 */       } else if ((op instanceof IntersectionQueryOperation)) {
/* 460 */         if (!$assertionsDisabled) throw new AssertionError();
/* 461 */         ((IntersectionQueryOperation)op).pruneIncompatibleTargets(targets);
/*     */       }
/*     */       else {
/* 464 */         Set<QueryTarget> set = op.getQueryTargets();
/* 465 */         assert (set.size() == 1);
/* 466 */         assert ((set.contains(QueryTarget.UNSPECIFIED)) || (set.containsAll(targets)));
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   QueryOperation optimize(Mailbox mbox)
/*     */     throws ServiceException
/*     */   {
/* 500 */     for (int i = 0;; i++) { if (i >= this.operations.size()) break label93;
/* 501 */       QueryOperation op = (QueryOperation)this.operations.get(i);
/* 502 */       QueryOperation optimized = op.optimize(mbox);
/* 503 */       if (optimized == null) {
/* 504 */         this.operations.remove(i);
/* 505 */       } else if (op != optimized) {
/* 506 */         this.operations.remove(i);
/* 507 */         this.operations.add(optimized);
/* 508 */         break;
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */     label93:
/*     */     
/* 515 */     if (this.operations.isEmpty()) {
/* 516 */       return new NoTermQueryOperation();
/*     */     }
/*     */     
/*     */     label238:
/*     */     label339:
/* 521 */     for (int i = 0;; i++) { if (i >= this.operations.size()) break label345;
/* 522 */       QueryOperation lhs = (QueryOperation)this.operations.get(i);
/*     */       
/*     */ 
/*     */ 
/* 526 */       if ((lhs instanceof IntersectionQueryOperation)) {
/* 527 */         combineOps(lhs, false);
/* 528 */         this.operations.remove(i);
/* 529 */         break; }
/* 530 */       if ((lhs instanceof NoTermQueryOperation)) {
/* 531 */         Iterator i$ = this.operations.iterator(); for (;;) { if (!i$.hasNext()) break label238; QueryOperation op = (QueryOperation)i$.next();
/* 532 */           if ((op instanceof LuceneQueryOperation)) {
/* 533 */             this.operations.remove(i);
/* 534 */             break;
/*     */           }
/*     */         }
/* 537 */         return new NoResultsQueryOperation();
/*     */       }
/*     */       
/* 540 */       for (int j = i + 1;; j++) { if (j >= this.operations.size()) break label339;
/* 541 */         QueryOperation rhs = (QueryOperation)this.operations.get(j);
/* 542 */         QueryOperation joined = lhs.combineOps(rhs, false);
/* 543 */         if (joined != null) {
/* 544 */           this.operations.remove(j);
/* 545 */           this.operations.remove(i);
/* 546 */           this.operations.add(joined);
/* 547 */           break;
/*     */         }
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */     label345:
/*     */     
/*     */ 
/* 556 */     Set<QueryTarget> targets = getQueryTargets();
/* 557 */     if (targets.isEmpty()) {
/* 558 */       ZimbraLog.search.debug("ELIMINATING %s b/c of incompatible QueryTargets", new Object[] { this });
/* 559 */       return new NoResultsQueryOperation();
/*     */     }
/*     */     
/* 562 */     pruneIncompatibleTargets(targets);
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 572 */     int distributeLhs = -1;
/* 573 */     for (int i = 0; i < this.operations.size(); i++) {
/* 574 */       QueryOperation lhs = (QueryOperation)this.operations.get(i);
/* 575 */       if (((lhs instanceof UnionQueryOperation)) || (lhs.getQueryTargets().size() > 1))
/*     */       {
/*     */ 
/* 578 */         distributeLhs = i;
/* 579 */         break;
/*     */       }
/*     */     }
/*     */     
/* 583 */     if (distributeLhs >= 0)
/*     */     {
/* 585 */       UnionQueryOperation lhs = (UnionQueryOperation)this.operations.remove(distributeLhs);
/* 586 */       UnionQueryOperation topOp = new UnionQueryOperation();
/*     */       
/* 588 */       for (QueryOperation lhsCur : lhs.operations) {
/* 589 */         newAnd = new IntersectionQueryOperation();
/* 590 */         topOp.add(newAnd);
/*     */         
/* 592 */         newAnd.addQueryOp(lhsCur);
/*     */         
/* 594 */         for (QueryOperation rhsCur : this.operations) {
/* 595 */           newAnd.addQueryOp((QueryOperation)rhsCur.clone());
/*     */         }
/*     */       }
/*     */       
/*     */       IntersectionQueryOperation newAnd;
/* 600 */       return topOp.optimize(mbox);
/*     */     }
/*     */     
/*     */ 
/* 604 */     assert (QueryTarget.getExplicitTargetCount(getQueryTargets()) <= 1);
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 613 */     LuceneQueryOperation lop = null;
/* 614 */     for (Iterator<QueryOperation> iter = this.operations.iterator(); iter.hasNext();) {
/* 615 */       QueryOperation op = (QueryOperation)iter.next();
/* 616 */       if ((op instanceof LuceneQueryOperation)) {
/* 617 */         lop = (LuceneQueryOperation)op;
/* 618 */         iter.remove();
/* 619 */         break;
/*     */       }
/*     */     }
/* 622 */     if (lop != null) {
/* 623 */       boolean foundIt = false;
/* 624 */       for (QueryOperation op : this.operations) {
/* 625 */         if ((op instanceof DBQueryOperation)) {
/* 626 */           ((DBQueryOperation)op).setLuceneQueryOperation(lop);
/* 627 */           foundIt = true;
/*     */         }
/*     */       }
/* 630 */       if (!foundIt)
/*     */       {
/* 632 */         addQueryOp(lop);
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */ 
/* 638 */     if (this.operations.size() == 1) {
/* 639 */       return (QueryOperation)this.operations.get(0);
/*     */     }
/*     */     
/* 642 */     return this;
/*     */   }
/*     */   
/*     */   String toQueryString()
/*     */   {
/* 647 */     StringBuilder ret = new StringBuilder("(");
/*     */     
/* 649 */     boolean atFirst = true;
/*     */     
/* 651 */     for (QueryOperation op : this.operations) {
/* 652 */       if (!atFirst) {
/* 653 */         ret.append(" AND ");
/*     */       }
/* 655 */       ret.append(op.toQueryString());
/* 656 */       atFirst = false;
/*     */     }
/*     */     
/* 659 */     ret.append(')');
/* 660 */     return ret.toString();
/*     */   }
/*     */   
/*     */   public String toString()
/*     */   {
/* 665 */     StringBuilder retval = new StringBuilder("INTERSECTION[");
/*     */     
/* 667 */     boolean atFirst = true;
/*     */     
/* 669 */     for (QueryOperation op : this.operations) {
/* 670 */       if (atFirst) {
/* 671 */         atFirst = false;
/*     */       } else {
/* 673 */         retval.append(" AND ");
/*     */       }
/* 675 */       retval.append(op.toString());
/*     */     }
/* 677 */     retval.append(']');
/* 678 */     return retval.toString();
/*     */   }
/*     */   
/*     */   public Object clone()
/*     */   {
/* 683 */     assert (this.messageGrouper == null);
/* 684 */     IntersectionQueryOperation result = (IntersectionQueryOperation)super.clone();
/* 685 */     result.bufferedNext = new ArrayList(1);
/* 686 */     result.operations = new ArrayList(this.operations.size());
/* 687 */     for (QueryOperation op : this.operations) {
/* 688 */       result.operations.add((QueryOperation)op.clone());
/*     */     }
/* 690 */     return result;
/*     */   }
/*     */   
/*     */   protected QueryOperation combineOps(QueryOperation other, boolean union)
/*     */   {
/* 695 */     if ((!union) && ((other instanceof IntersectionQueryOperation))) {
/* 696 */       addQueryOps(((IntersectionQueryOperation)other).operations);
/* 697 */       return this;
/*     */     }
/* 699 */     return null;
/*     */   }
/*     */   
/*     */   protected void begin(QueryOperation.QueryContext ctx) throws ServiceException
/*     */   {
/* 704 */     assert (this.context == null);
/*     */     
/* 706 */     this.context = new QueryOperation.QueryContext(ctx.getMailbox(), ctx.getResults(), ctx.getParams(), (ctx.getChunkSize() + 1) * 3);
/* 707 */     this.messageGrouper = new HitGrouper[this.operations.size()];
/*     */     
/* 709 */     for (int i = 0; i < this.operations.size(); i++) {
/* 710 */       QueryOperation op = (QueryOperation)this.operations.get(i);
/* 711 */       op.begin(ctx);
/* 712 */       this.messageGrouper[i] = new HitGrouper(op, this.context.getResults().getSortBy());
/*     */       
/* 714 */       if (!op.hasNext())
/*     */       {
/*     */ 
/*     */ 
/* 718 */         ZimbraLog.search.debug("Dropping out of intersect query since we got to 0 results on execution %d out of %d", new Object[] { Integer.valueOf(i + 1), Integer.valueOf(this.operations.size()) });
/*     */         
/*     */ 
/*     */ 
/*     */ 
/* 723 */         for (int j = 0; j <= i; j++) {
/* 724 */           Closeables.closeQuietly((Closeable)this.operations.get(j));
/*     */         }
/*     */         
/* 727 */         this.operations.clear();
/* 728 */         this.messageGrouper = new HitGrouper[1];
/*     */         
/* 730 */         QueryOperation nullOp = new NoResultsQueryOperation();
/* 731 */         addQueryOp(nullOp);
/* 732 */         this.messageGrouper[0] = new HitGrouper(nullOp, this.context.getResults().getSortBy());
/* 733 */         return;
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   public List<QueryInfo> getResultInfo()
/*     */   {
/* 740 */     List<QueryInfo> result = new ArrayList();
/* 741 */     for (QueryOperation op : this.operations) {
/* 742 */       result.addAll(op.getResultInfo());
/*     */     }
/* 744 */     return result;
/*     */   }
/*     */   
/*     */   protected void depthFirstRecurse(QueryOperation.RecurseCallback cb)
/*     */   {
/* 749 */     for (QueryOperation op : this.operations) {
/* 750 */       op.depthFirstRecurse(cb);
/*     */     }
/* 752 */     cb.recurseCallback(this);
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/index/IntersectionQueryOperation.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */